1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| #include <cstdio> #include <queue> #include <cstring> const int INF = 0x3f3f3f3f; const int maxn = 3005; using namespace std; struct E{ int to, nxt, f; }e[maxn << 1]; int head[maxn], tot = -1; void addedge(int u, int v, int f){ e[++tot].to = v, e[tot].nxt = head[u], e[tot].f = f; head[u] = tot; } void ins(int u, int v, int f){ addedge(u, v, f); addedge(v, u, 0); } int n, m, keep[maxn], dep[maxn]; bool bfs(){ queue <int> q; q.push(0); memset(dep, 0, sizeof dep); dep[0] = 1; while (!q.empty()){ int cur = q.front(); q.pop(); for (int i = head[cur]; i != -1; i = e[i].nxt) if (!dep[e[i].to] && e[i].f){ dep[e[i].to] = dep[cur] + 1; q.push(e[i].to); } } return dep[n + m + 1]; } int dfs(int cur, int Max){ if (cur == n + m + 1) return Max; for (int i = head[cur]; i != -1; i = e[i].nxt){ if (dep[e[i].to] == dep[cur] + 1 && e[i].f){ if (int flow = dfs(e[i].to, min(Max - flow, e[i].f))){ e[i].f -= flow; e[i ^ 1].f += flow; return flow; } } } return 0; } int maxflow = 0; void Dinic(){ while (bfs()){ while (int tmp = dfs(0, INF)) maxflow += tmp; } } int main(){ memset(head, -1, sizeof head); scanf("%d%d", &n, &m); for (int f, i = 1; i <= n; i++){ scanf("%d", &f); ins(0, i, f); } for (int i = 1; i <= m; i++){ int k, M; scanf("%d", &k); for (int a, j = 1; j <= k; j++){ scanf("%d", &a); if (keep[a] == 0) ins(a, i + n, INF); else ins(keep[a], i + n, INF); keep[a] = i + n; } scanf("%d", &M); ins(i + n, n + m + 1, M); } Dinic(); printf("%d\n", maxflow); return 0; }
|